// #include <iostream>
// #include <cmath>
// using namespace std;
// // zdl:: 这道题目比较难弄的地方就是需要处理的细节，这个非常的关键！
// using ll = long long;
// const int N = 1e6 + 10;
// bool st[N];
// int p[N];
// int cnt;
// bool ret[N];

// int l, r;
// void get_prime()
// {
//     int n = sqrt(r);
//     for (ll i = 2; i <= n; i++)
//     {
//         if (!st[i])
//             p[++cnt] = i;

//         for (int j = 1; j <= cnt && i * p[j] <= n; j++)
//         {
//             st[i * p[j]] = true;
//             if (i % p[j] == 0)
//                 break;
//         }
//     }
// }

// int main()
// {
//     cin >> l >> r;
//     get_prime();
//     l == 1 ? 2 : l;
//     // 区间映射
//     for (int i = 1; i <= cnt; i++)
//     {
//         ll x = p[i];
//         for (ll j = max(x * 2, (x + l - 1) / x * x); j <= r; j += x)
//         {
//             ret[j - l] = true;
//         }
//     }
//     int count = 0;

//     for (int i = l; i <= r; i++)
//     {
//         if (!ret[i - l])
//             count++;
//     }

//     cout << count << endl;
//     return 0;
// }


// 这道题目还是存在很多比较坑的地方
//  首先使用 欧拉筛 和 相应的细节处理


#include<iostream>

using namespace std;
int l, r;
const int N = 1e6 + 10;
int p[N], cnt;
bool ret[N], st[N];
using ll = long long;


void get_prime()
{
    ll x = sqrt(r);
    // 接下来的逻辑就是欧拉晒
    for (ll i = 2; i <= x; i++)
    {
        if (!st[i]) p[++cnt] = i;
        for (ll j = 1; i * p[j] <= x; j++)
        {
            st[p[j] * i] = true;
            if (i % p[j] == 0) break;
        }
    }    
}
int main()
{

    cin >> l >> r;
    get_prime();
    //现在我们就开始处理细节问题·
    l = l == 1 ? 2 : l;

    // 现在开始完成这个逻辑
    //通过推理我们可以知道使用 1- sqrt(n)之间的所有的质数，，就可以筛掉这些区间内的所有的和数
    for (int i = 1; i <= cnt; i++)
    {
        ll x = p[i];
        for (ll j = max(2 * x, (x + l - 1) / x * x); j <= r; j+= x)
        {
            ret[j - l] = true;
        }
    }
    int sum = 0;
    for (int i = l; i <= r; i++)
    {
        if (!ret[i - l]) sum++;
    }

    cout << sum << endl;
    return 0;
}